<<<<<<< HEAD
const dataKit = require("./dataKit")
const dateKit = require("./dateKit")
const util = require('./util.js')
/**
 * 注意：使用await的方法必须加上async，不然会报错！！
 */
module.exports = {
    /**
    * 更新数据
    * @param {*} context 会话
    * @param {*} tableName  表名
    * @param {*} filter  新数据
    * @param {*} data  新数据
    * @result  data  返回对象
    */
    async update(context, tableName, filter, data) {
        if (!filter) {
            const msg = "filter不存在，无法更新";
            console.info(msg);
            return { code: -1, msg: msg }
        }
        const cloud = context.cloud;
        const result = await cloud.db.collection(tableName).updateMany(
            filter,
            { $set: data }
        );
        console.info("updateMany done, result:", result)
        return result;
    },
    /**
     * 根据名称获取商户
     * @param {*} openId 商户的openid
     */
    async getUserByOpenId(context, openId) {
        //过滤条件
        const filter = { openId: openId };
        let merchant = await dataKit.findOne(context, "user_info", filter);
        return merchant;
    },
    /**
     * 根据openId获取商户
     * @param {*} openId 商户的openid
     */
    async getMerchantByOpenId(context, openId) {
        if (!openId) {
            console.info("getMerchantByOpenId --> openId是必须的");
            return null;
        }
        //过滤条件
        const filter = { openId: openId };
        let merchant = await dataKit.findOne(context, "merchant_info", filter);
        return merchant;
    },
    /**
     * 获取商户的AccessToken
     * @param {*} openId 商户的openid
     */
    async getMerchantAccessToken(context, openId) {
        const merchant = await this.getMerchantByOpenId(context, openId);
        return merchant.accessToken;
    },
    /**
     * 获取商户唯一的商户AccessToken
     */
    async getDefaultMerchantAccessToken(context) {
        //过滤条件
        const filter = {};
        let merchant = await dataKit.findOne(context, "merchant_info", filter);
        return merchant.accessToken;
    },
    /**
     * 商品列表
     * @param {*} context 
     * @param {*} openId 商户的openid
     * @param {*} cid 类目id
     */
    async getProductList(context) {
        const accessToken = await this.getDefaultMerchantAccessToken(context);
        const result = await context.cloud.topApi.invoke({
            api: 'taobao.items.onsale.get',
            autoSession: false,
            data: {
                session: accessToken,
                fields: "num_iid,title,cid,price,pic_url",
                page_size: 200
            }
        });
        return result;
    },
    /**
     * 判断用户是否是会员
     * @param {*} context 上下文
     * @param {*} access_token 商家 token
     * @param {*} mix_nick 用户 mix_nick
     */
    async taobaoApiToMember(context, access_token, mix_nick) {
        const identity = await context.cloud.topApi.invoke({
            api: 'taobao.crm.member.identity.get',
            autoSession: false,
            data: {
                session: access_token,
                mix_nick: mix_nick
            }
        });
        if (identity.result.member_info) {// 是会员
            return { flag: true };
        } else {
            return { flag: false };
        }
    },
    /**
     * 查询用户淘宝订单列表
     * @param {*} context 
     * @param {*} access_token 商家 token
     * @param {*} open_id 用户open_id
     * @param {Object} param 参数
     *  @param {String} access_token 用户token
     *  @param {String} open_id 用户 open_id
     *  @param {String} start_created 查询范围开始时间
     *  @param {String} end_created 结束时间
     */
    async taobaoApiToSoldOrders(context, param) {
        const trades = await context.cloud.topApi.invoke({
            api: 'taobao.open.trades.sold.get',
            autoSession: false,
            data: {
                session: param.access_token,
                fields: 'tid,orders,created,status',
                buyer_open_id: param.openId,
                // buyer_open_id: 'AAE_2K8_AMYB12Kq6O03zKh_',
                start_created: param.start_time,
                end_created: param.end_time,
                //type: 'tmall_i18n',
                //status: 'TRADE_FINISHED',// 交易成功   //WAIT_BUYER_PAY    付定金
                page_no: 1,
                page_size: 100
            }
        });

        return trades

        // 判断用户是否有购买过订单
        if (!trades || total_results <= 0) {
            return false;
        } else {
            return true;
        }
    },
    /**
     * 增加抽奖机会
     * @param {*} content 
     * @param {*} num 增加的幸运值数量 
     * @param {*} nick_name 
     * @param {*} openId 
     */
    async add(content, num, nick_name, openId) {
        const currentTime = dateKit.getCurrentDateTime()

        let result = await dataKit.findOne(content, 'ticket',
            {
                openId: openId
            }
        );

        if (!result) {
            result = {
                openId: openId,
                nick_name: nick_name,
                create_time: currentTime,
                update_time: currentTime,
                ticket_time: '',
                ticket_id: [],
                luck_value: 0,
                num: [], //该num值为卡片的序号值
                count: 2,
                flag: 0
            }
        }

        result.update_time = currentTime
        result.luck_value = result.luck_value + num
        await dataKit.insertOrUpdate(content, 'ticket', result)
    },
    /**
     * 抽卡
     * @param {*} content 
     * @param {*} num 卡片序号
     * @param {*} openId 
     * @param {*} count  每日抽卡的次数 
     * @param {*} flag  判断是第几次抽卡，决定中奖概率
     */
    async card(content, num, result, count, flag) {
        const currentTime = dateKit.getCurrentDateTime()

        if (num === null || num === undefined) {
            console.log('==============没有传递正确的num值============')
            return false
        }

        //取出卡片
        let card = await dataKit.findOne(content, 'cards',
            {
                num: num
            }
        );
        console.info('抽出的卡片为：', card)

        result.update_time = currentTime
        result.luck_value = result.luck_value - 2 // 抽卡消耗2点幸运值
        result.ticket_id.push(card._id)
        result.num.push(num)
        result.count = count
        result.ticket_time = currentTime
        result.flag = flag
        await dataKit.insertOrUpdate(content, 'ticket', result)

        //返回卡片信息给前端
        return card;
    },
    /**
     * 测试文字识别
     * @param {*} context 
     * @param {*} access_token 
     * @param {*} mix_nick 
     */
    async test(context) {
        const identity = await context.cloud.topApi.invoke({
            api: 'aliyun.viapi.ocr.character',
            autoSession: false,
            data: {
                image_url: "https://img.alicdn.com/imgextra/i1/4161056916/O1CN01rmLoNz20xZobkRvUq_!!4161056916.jpg",
                min_height: 1000
            }
        });

        return identity;
    },
    /**
     * 是否中奖
     * @param {*} content 
     */
    async isGift(content, openId) {
        let result = await dataKit.findOne(content, 'gift_record',
            {
                openId: openId
            }
        );

        return result;
    },
    /**
     * 用户抽取优惠券消耗幸运值
     * @param {*} content 
     * @param {*} openId 
     */
    async decreame(content, openId) {
        let result = await dataKit.findOne(content, 'ticket',
            {
                openId: openId
            }
        );

        result.luck_value = result.luck_value - 1
        await dataKit.updateBy_id(content, 'ticket', result)
    },
    /**
     * 修改抽奖表，规约每日只能抽取一次奖品
     * @param {*} content 
     * @param {*} param 抽奖表 
     */
    async raffle(content, param) {
        param.update_time = dateKit.getCurrentDateTime()
        await dataKit.updateBy_id(content, 'raffle', param)
    },
    /**
     * (用户第一次抽奖，新建该表)
     * @param {*} content 
     * @param {*} param 抽奖表 
     * @param {*} ticket 
     */
    async first(content, openId, nick_name) {
        const c = dateKit.getCurrentDateTime()

        var param = {
            openId: openId,
            create_time: c,
            update_time: c,
            gift_id: [],
            count: 2,
            nick_name: nick_name
        }

        await dataKit.insertOne(content, 'raffle', param)
    },
    /**
     * 判断数组是否包含
     * @param {*} arr 
     * @param {*} item 
     */
    contain(arr, item) {
        if (arr != null && arr.length > 0 && arr != undefined) {
            for (let key of arr) {
                if (item === key) {
                    return true
                }
            }

            return false
        }

        return false
    },
    /**
     * 层级抽卡,根据数组来判断是24号前还是后
     * 根据bool得知是否中奖
     * @param {*} result 
     * @param {*} count 今日还剩几次抽卡，1表示第一次，0表示今日两次机会完了
     * rate 中奖的概率
     * arr 用来操作的数组
     * num 抽卡层级，分别为1,2，3
     */
    async one(result, count, twoFourArr, rate, content, num, openId) {
        console.info('==========one is running==============')
        const currentTime = dateKit.getCurrentDateTime()

        const r = dateKit.getRandom(1, 100)

        if (r > rate) {
            console.log('没有抽中卡片修改相关数据')
            result.flag = num
            result.update_time = currentTime
            result.ticket_time = currentTime
            result.luck_value = result.luck_value - 2

            if (result.count === 1) {
                result.count = result.count - 1
            } else if (result.count === 0) {
                //此处表示今日重置次数
                result.count = 1
            } else {
                result.count = result.count - 1
            }

            await dataKit.insertOrUpdate(content, 'ticket', result)

            return false
        }

        var residueArr = result.num //使用卡片序号获取没有抽中的卡片
        console.log('已经抽中的塔罗牌：', residueArr)

        for (let index = 0; index < twoFourArr.length; index++) {
            //把已经中奖的卡片排出去
            for (let i = 0; i < residueArr.length; i++) {
                if (twoFourArr[index] == residueArr[i]) {
                    twoFourArr.splice(index, 1)
                    index = index - 1
                    break
                }
            }
        }

        console.log('最后排除后的数组为：', twoFourArr)
        let twoResult = dateKit.getRandom(0, twoFourArr.length - 1)

        console.log('最后的随机结果为：', twoResult)
        console.log('传递的num值为：', twoFourArr[twoResult])
        let lastResult = await this.card(content, twoFourArr[twoResult], result, count, 1) //抽中了则需要把flag重置为1层级

        if (lastResult) {
            return { code: 0, data: lastResult }
        }

        console.log('card方法出错，card结果为：', lastResult)
        return false
    },
    /**
     * @return 返回奖品信息【1】，否则全部为没有中奖
     * @param {*} content 
     * @param {*} len 塔罗牌数量
     * @param {*} raffle raffle信息
     * @param {*} ticket  ticket信息
     */
    async gift01(content, len, raffle, ticket, openId, nick_name) {
        const currTime = dateKit.getCurrentDateTime()

        if (!len) {
            return { code: -1, msg: '传入的塔罗牌数量为空' }
        }

        var wu = await dataKit.findOne(content, 'gift',
            {
                num: 1
            }
        );

        console.log('传入的len为：', len)
        //每个等级都可以抽取优惠券
        switch (len) {
            case 1:
            case 2:
                let r = dateKit.getRandom(1, 1000)
                if (wu.rate >= r) {
                    //抽中奖品,判断库存
                    if (wu.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.quan(wu, raffle, content)
                    return { code: 1, data: wu } //抽中奖品后返回信息
                }

                await this.without(raffle, content)
                return { code: 0, msg: '' }
            case 3:
            case 4: //可以抽中1和3
                let three = await dataKit.findOne(content, 'gift',
                    {
                        num: 3
                    }
                );

                let x = dateKit.getRandom(1, 1000)

                //抽去1
                if (wu.rate > x) {
                    if (wu.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.quan(wu, raffle, content)
                    return { code: 1, data: wu } //抽中奖品后返回信息
                }

                if (three.rate >= x) {
                    //抽中奖品,判断库存
                    if (three.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(three, raffle, openId, nick_name, content)
                    return { code: 1, data: three }
                }

                await this.without(raffle, content)
                return { code: 0, msg: '' }
            case 5: //可以抽取1和3和5
                let five = await dataKit.findOne(content, 'gift',
                    {
                        num: 5
                    }
                );

                let y = dateKit.getRandom(1, 1000)

                //抽去1
                if (wu.rate > y) {
                    if (wu.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.quan(wu, raffle, content)
                    return { code: 1, data: wu } //抽中奖品后返回信息
                }

                //抽取3
                let three01 = await dataKit.findOne(content, 'gift',
                    {
                        num: 3
                    }
                );

                if (three01.rate >= y) {
                    //抽中奖品,判断库存
                    if (three01.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(three01, raffle, openId, nick_name, content)
                    return { code: 1, data: three01 }
                }

                if (five.rate >= y) {
                    //抽中奖品,判断库存
                    if (five.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(five, raffle, openId, nick_name, content)
                    return { code: 1, data: five }
                }

                await this.without(raffle, content)
                return { code: 0, msg: '' }
            case 6: //还可以抽取1,3,5,6
                let six = await dataKit.findOne(content, 'gift',
                    {
                        num: 6
                    }
                );

                let s = dateKit.getRandom(1, 1000)

                //抽去1
                if (wu.rate > s) {
                    if (wu.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.quan(wu, raffle, content)
                    return { code: 1, data: wu } //抽中奖品后返回信息
                }

                //抽取3
                let three02 = await dataKit.findOne(content, 'gift',
                    {
                        num: 3
                    }
                );

                if (three02.rate >= s) {
                    //抽中奖品,判断库存
                    if (three02.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(three02, raffle, openId, nick_name, content)
                    return { code: 1, data: three02 }
                }

                //抽取5
                let five01 = await dataKit.findOne(content, 'gift',
                    {
                        num: 5
                    }
                );

                if (five01.rate >= s) {
                    //抽中奖品,判断库存
                    if (five01.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(five01, raffle, openId, nick_name, content)
                    return { code: 1, data: five01 }
                }

                if (six.rate >= s) {
                    //抽中奖品,判断库存
                    if (six.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(six, raffle, openId, nick_name, content)
                    return { code: 1, data: six }
                }

                await this.without(raffle, content)
                return { code: 0, msg: '' }
            case 7: //可以抽取1,3,5,6,7
            case 8:
                let theven = await dataKit.findOne(content, 'gift',
                    {
                        num: 7
                    }
                );

                let t = dateKit.getRandom(1, 1000)

                //抽去1
                if (wu.rate > t) {
                    if (wu.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.quan(wu, raffle, content)
                    return { code: 1, data: wu } //抽中奖品后返回信息
                }

                //抽取3
                let three03 = await dataKit.findOne(content, 'gift',
                    {
                        num: 3
                    }
                );

                if (three03.rate >= t) {
                    //抽中奖品,判断库存
                    if (three03.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(three03, raffle, openId, nick_name, content)
                    return { code: 1, data: three03 }
                }

                //抽取5
                let five02 = await dataKit.findOne(content, 'gift',
                    {
                        num: 5
                    }
                );

                if (five02.rate >= t) {
                    //抽中奖品,判断库存
                    if (fivfive02e.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(five02, raffle, openId, nick_name, content)
                    return { code: 1, data: five02 }
                }

                //抽取6
                let six01 = await dataKit.findOne(content, 'gift',
                    {
                        num: 6
                    }
                );

                if (six01.rate >= t) {
                    //抽中奖品,判断库存
                    if (six01.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(six01, raffle, openId, nick_name, content)
                    return { code: 1, data: six01 }
                }

                if (theven.rate >= t) {
                    //抽中奖品,判断库存
                    if (theven.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(theven, raffle, openId, nick_name, content)
                    return { code: 1, data: theven }
                }

                await this.without(raffle, content)
                return { code: 0, msg: '' }
            default:
                raffle.count = raffle.count - 1
                raffle.update_time = currTime //最后一次抽奖时间
                raffle.ticket_time = currTime
                await dataKit.insertOrUpdate(content, 'raffle', raffle)
                return { code: -2, msg: '该塔罗牌数量不能抽奖' };
        }
    },
    /**
     * 抽奖接口，支持按照平均每天的形式来分发奖品
     * 中奖形式按照数组来做
     * 加一个字段is_dup来控制该奖品是否可以重复被抽中
     * 此方法的raffle表一定不能为空，在index中提前进行一次新建操作
     * 
     * 涉及表：gift（奖品表），record（中奖记录表），raffle（中奖需要的条件信息，比如一天几次）
     * @param {*} content 
     * @param {*} raffle 
     * @param {*} openId 
     * @param {*} nick_name 
     */
    async giftByArr(content, raffle, openId, nick_name) {
        const currentStamp = dateKit.getRealTime()

        let start_time = dateKit.changeToTimestamp('2020-11-01')
        let end_time = dateKit.changeToTimestamp('2020-11-01')

        if (currentStamp > end_time || currentStamp < start_time) {
            return { code: -1, msg: '当前时间不在抽奖时间里面' }
        }

        let giftResult = await dataKit.find(content, 'gift', {})

        //产生的随机数
        let r = dateKit.getRandom(1, 100)

        var gift;

        if (new Date(currentStamp).toDateString() === new Date(raffle.ticket_time).toDateString()) {
            if (raffle.count <= 0) {
                return { code: -2, msg: '今日抽奖次数已经上限' }
            }

            //执行抽奖逻辑
            for (let i = 0; i < giftResult.length; i++) {
                let rate = giftResult[i].rate
                if (r <= rate[1] && r >= rate[0]) {
                    gift = giftResult[i]
                }
            }

            console.log('抽中的奖品是：', gift)
            if (!gift) {
                console.log('没有匹配的奖品，该区间为不中奖')
                await this.without(raffle, content)
                return { code: -3, msg: '很遗憾没有抽中奖品' }
            }

            //判断库存,此处涉及到数字切记不要当成对象来判断，注意01操作
            if (gift.count != null && gift.count != undefined) {
                if (gift.count <= 0) {
                    console.log('该奖品库存不足')
                    await this.without(raffle, content)
                    return { code: -3, msg: '很遗憾没有抽中奖品' }
                }
            }

            //判断每天的库存数量
            if (gift.day_count != null && gift.day_count != undefined) {
                if (gift.day_count <= 0) {
                    console.log('该奖品今日抽取数量已经上限')
                    await this.without(raffle, content)
                    return { code: -3, msg: '很遗憾没有抽中奖品' }
                }
            }

            //判断该奖品是否可以被重复抽中,0表示可以被重复抽中，1表示不可以被重复抽中
            if (gift.is_dup) {
                let record = await dataKit.findOne(content, 'record',
                    {
                        openId: openId,
                        gift_id: gift._id
                    }
                )

                if (record) {
                    console.log('该奖品不能重复抽中')
                    await this.without(raffle, content)
                    return { code: -3, msg: '很遗憾没有抽中奖品' }
                }
            }

            //乐观锁判断库存，该处已经修改过奖品表了，因此后续切记不要重复扣减库存
            let version = gift.version
            gift.version++;
            gift.count--;

            let updateResult = await dataKit.update(content, 'gift',
                {
                    version: version,
                    _id: gift._id
                },
                gift
            );

            if (updateResult === 0) {
                await this.without(raffle, content)
                console.log('该奖品已经被修改过')
                return { code: -3, msg: '很遗憾没有抽中奖品' }
            }

            //抽中奖品，执行数据表修改
            await this.sure(gift, raffle, openId, nick_name)
            return { code: 0, data: gift }
        }

        //第二天，则不用判断抽奖次数
        //执行抽奖逻辑
        for (let i = 0; i < giftResult.length; i++) {
            let rate = giftResult[i].rate
            if (r <= rate[1] && r >= rate[0]) {
                gift = giftResult[i]
            }
        }

        console.log('抽中的奖品是：', gift)
        if (!gift) {
            console.log('没有匹配的奖品，该区间为不中奖')
            await this.without(raffle, content)
            return { code: -3, msg: '很遗憾没有抽中奖品' }
        }

        //判断库存,此处涉及到数字切记不要当成对象来判断，注意01操作
        if (gift.count != null && gift.count != undefined) {
            if (gift.count <= 0) {
                console.log('该奖品库存不足')
                await this.without(raffle, content)
                return { code: -3, msg: '很遗憾没有抽中奖品' }
            }
        }

        //判断每天的库存数量
        if (gift.day_count != null && gift.day_count != undefined) {
            if (gift.day_count <= 0) {
                console.log('该奖品今日抽取数量已经上限')
                await this.without(raffle, content)
                return { code: -3, msg: '很遗憾没有抽中奖品' }
            }
        }

        //判断该奖品是否可以被重复抽中,0表示可以被重复抽中，1表示不可以被重复抽中
        if (gift.is_dup) {
            let record = await dataKit.findOne(content, 'record',
                {
                    openId: openId,
                    gift_id: gift._id
                }
            )

            if (record) {
                console.log('该奖品不能重复抽中')
                await this.without(raffle, content)
                return { code: -3, msg: '很遗憾没有抽中奖品' }
            }
        }

        //乐观锁判断库存，该处已经修改过奖品表了，因此后续切记不要重复扣减库存
        let version = gift.version
        gift.version++;
        gift.count--;

        let updateResult = await dataKit.update(content, 'gift',
            {
                version: version,
                _id: gift._id
            },
            gift
        );

        if (updateResult === 0) {
            await this.without(raffle, content)
            console.log('该奖品已经被修改过')
            return { code: -3, msg: '很遗憾没有抽中奖品' }
        }

        //抽中奖品，执行数据表修改
        await this.sure(gift, raffle, openId, nick_name)
        return { code: 0, data: gift }
    },
    /**
     * 没有中奖修改抽奖表，后续如果有什么扣减积分的操作也是可以新增字段的
     */
    async without(raffle, content) {
        const currTime = dateKit.getCurrentDateTime()
        raffle.count = raffle.count - 1
        raffle.update_time = currTime
        raffle.ticket_time = currTime //最后一次抽奖时间
        await dataKit.insertOrUpdate(content, 'raffle', raffle)
    },
    /**
     * 中奖
     * @param {*} result  gift信息
     * @param {*} raffle  raffle信息
     */
    async sure(result, raffle, openId, nick_name, content) {
        console.log('sure方法执行成功')
        const currTime = dateKit.getCurrentDateTime()

        //抽中奖品修改相关表
        //1. gift
        // result.count = result.count - 1
        result.day_count = result.day_count - 1
        await dataKit.insertOrUpdate(content, 'gift', result)

        //2. raffle, 在index需要判断今日是否还能抽奖,并重置[如果是第一次则先新增数据]
        raffle.count = raffle.count - 1
        raffle.update_time = currTime //最后一次抽奖时间
        raffle.ticket_time = currTime
        raffle.gift_id.push(result._id)
        await dataKit.insertOrUpdate(content, 'raffle', raffle)

        //3.record 独立一个奖品记录表
        let record = {
            openId: openId,
            nick_name: nick_name,
            create_time: currTime,
            gift_id: result._id,
            gift_name: result.name
        }

        await dataKit.insertOne(content, 'record', record)
    },
    /**
     * 查询每日的一个中奖名单
     */
    async queryGiftRecord(content, openId) {
        const currentDate = dateKit.getCurrentDate()
        let start = currentDate + ' 00:00:00'
        let end = currentDate + ' 23:59:59'

        //该表记得添加联合索引
        let result = await dataKit.find(content, 'record', 
            {
                create_time: {
                    $gte: start,
                    $lte: end
                },
                openId: openId
            }
        );

        return result
    },
    /**
     * 浏览商品到达一定数量后增加幸运值
     * @param {*} product 
     * @param {*} content 
     * @param {*} nick_name 
     * @param {*} openId 
     */
    async viewAdd(product, content, nick_name, openId) {
        console.log('viewAdd方法执行============')
        var len = product.goods_id.length

        let a = parseInt(len / 5)
        if (a <= 3 && a > 0) {
            //第几个5次
            switch (a) {
                case 1:
                    //判断是否增加过幸运值
                    if (product.count === 2) {
                        return { msg: '已经增加幸运奖' }
                    }

                    this.add(content, 1, nick_name, openId)

                    //把浏览商品表数据修改
                    product.count = 2
                    await dataKit.updateBy_id(content, 'product', product)
                    return;
                case 2:
                    //判断是否增加过幸运值
                    if (product.count === 1) {
                        return { msg: '已经增加幸运奖' }
                    }

                    this.add(content, 1, nick_name, openId)

                    //把浏览商品表数据修改
                    product.count = 1
                    await dataKit.updateBy_id(content, 'product', product)
                    return;
                case 3:
                    //判断是否增加过幸运值
                    if (product.count === 0) {
                        return { msg: '已经增加幸运奖' }
                    }

                    this.add(content, 1, nick_name, openId)

                    //把浏览商品表数据修改
                    product.count = 0
                    await dataKit.updateBy_id(content, 'product', product)
                    return;
                default:
                    return
            }
        }
        let count = parseInt(a / 3) //整除两次得到第几次机会
        if (count > 0) {
            //第几个5次
            switch (count) {
                case 1:
                    //判断是否增加过幸运值
                    if (product.count === 2) {
                        return { msg: '已经增加幸运奖' }
                    }

                    this.add(content, 1, nick_name, openId)

                    //把浏览商品表数据修改
                    product.count = 2
                    await dataKit.updateBy_id(content, 'product', product)
                    return;
                case 2:
                    //判断是否增加过幸运值
                    if (product.count === 1) {
                        return { msg: '已经增加幸运奖' }
                    }

                    this.add(content, 1, nick_name, openId)

                    //把浏览商品表数据修改
                    product.count = 1
                    await dataKit.updateBy_id(content, 'product', product)
                    return;
                case 3:
                    //判断是否增加过幸运值
                    if (product.count === 0) {
                        return { msg: '已经增加幸运奖' }
                    }

                    this.add(content, 1, nick_name, openId)

                    //把浏览商品表数据修改
                    product.count = 0
                    await dataKit.updateBy_id(content, 'product', product)
                    return;
                default:
                    return
            }
        }
    },
    /**
    * 执行成功
    * @param {*} data 
    */
    toSuccess(data) {
        if (data) {
            return { code: 0, msg: '操作成功', data: data }
        }

        return { code: 0, msg: '操作成功' }
    },
    /**
     * 执行失败
     * @param {*} msg 
     */
    toFail(msg) {
        return { code: -1, msg: msg ? '操作失败' : msg }
    },
    /**对于数字类型的返回封装
     * @param {*} count
     * @param {*} value
     * @param {*} flag
     */
    toCount() {
        var len = arguments.length

        switch (len) {
            case 1:
                return { count: arguments[0] }
            case 2:
                return { count: arguments[0], value: arguments[1] }
            case 3:
                return { count: arguments[0], value: arguments[1], flag: arguments[2] }
            default:
                return this.toFail('暂时只支持3个值的传递')
        }
    },
    /**
     * 对于字符串类型字段的查询今日
     * @param {*} content 
     * @param {*} tableName 
     * @param {*} filter 
     */
    async getTodayData(content, tableName, filter) {
        let a = util.checkIsNull(content, tableName)
        if (!a) {
            return a
        }

        let currentDate = dateKit.getCurrentDate()

        let start = currentDate + ' 00:00:00'
        let end = currentDate + ' 23:59:59'

        const result = await dataKit.find(content, tableName,
            {
                create_time: {
                    $gte: start,
                    $lte: end
                }
            },
            filter
        )

        return result
    },
    /**
     * 获取格式化字符串时间的数据，该表应该被建立时间字段的一个索引
     * @param {*} content 
     * @param {*} tableName 
     * @param {*} start 开始时间（字符串类型）
     * @param {*} end 结束时间（字符串类型）
     * @param {*} filter 过滤条件，比如前10条数据
     */
    async getDataForStrDate(content, tableName, start, end, filter) {
        let a = util.checkIsNull(content, tableName, start, end)
        if (!a) {
            return a
        }

        let a = new Date(start)
        let b = new Date(end)

        if (a == 'Invalid Date' || b == 'Invalid Date') {
            return { code: -2, msg: '请传入正确格式的时间：\'2020-11-11 16:15:15\'' }
        }

        const result = await dataKit.find(content, tableName,
            {
                create_time: {
                    $gte: start,
                    $lte: end
                }
            },
            filter
        )

        return result
    },
    /**
     * 判断今日是否做过活动了（签到， 分享， 浏览商品， 收藏店铺， 购买， 入会）
     * 现在修改为每次打卡都是一条数据
     * @param {*} content 
     * @param {*} tableName 
     * @param {*} openId 
     * @param {*} keyName 用来判断今日活动的时间的属性名
     */
    async isActon(content, tableName, openId, keyName) {
        const result = await dataKit.findNew(content, tableName,
            {
                openId: openId
            }
        )

        if (!result) {
            return { flag: false }
        }

        const currentStamp = dateKit.getRealTime()

        let compareTime = new Date(dateKit.changeToTimestamp(result[keyName])).toDateString()
        if (new Date(currentStamp).toDateString() === compareTime) {
            return { flag: true }
        }

        return { flag: false }
    },
    /**
     * 返回今日活动还剩余的次数
     * @param {*} content 
     * @param {*} tableName 
     * @param {*} openId 
     * @param {*} keyName 数据表中时间的列名
     * @param {*} countName 数据表中次数的列名
     * @param {*} count 一天的次数
     */
    async getActionCount(content, tableName, openId, keyName, countName, count) {
        const result = await dataKit.findNew(content, tableName,
            {
                openId: openId
            }
        )

        if (!result) {
            //返回默认的最高次数
            return this.toCount(count)
        }

        const currentStamp = dateKit.getRealTime()

        let compareTime = new Date(dateKit.changeToTimestamp(result[keyName])).toDateString()
        if (new Date(currentStamp).toDateString() === compareTime) {
            return this.toCount(result[countName])
        }

        return this.toCount(count)
    },
    /**
     * 做完活动后减少每日可做该活动次数
     * @param {*} content 
     * @param {*} tableName 
     * @param {*} openId 
     * @param {*} nick_name 
     * @param {*} totalCount 一天可做活动总数
     */
    async actionDecCount(content, tableName, openId, nick_name, totalCount) {
        const currentTime = dateKit.getCurrentDateTime()

        const result = await dataKit.findNew(content, tableName,
            {
                openId: openId
            }
        )

        //次数名称定死为count
        if (!result) {
            result = {
                openId: openId,
                nick_name: nick_name,
                create_time: currentTime,
                update_time: currentTime,
                count: totalCount - 1
            }
            await dataKit.insertOne(content, tableName, result)

            return true
        }

        result.update_time = currentTime
        result.count = result.count - 1
        await dataKit.updateBy_id(content, tableName, result)
        return true
    },
    /**
     * 重置每日奖品为平均数量
     * @param {*} totalDay 需要抽奖的总时长
     */
    async resetGiftCount(content, totalDay) {
        let gift = await dataKit.find(content, 'gift', {})

        for (let index = 0; index < gift.length; index++) {
            let element = gift[index];
            if(element.day_count != null && element.day_count != undefined){
                //向下取整
                let countForDay = parseInt(element.count / totalDay)
                element.day_count = countForDay
                await dataKit.updateBy_id(content, 'gift', element)
            }
        }

        return '重置每日奖品数量成功了'
    },
    /**
     * 查询我的奖品列表
     * @param {*} content 
     * @param {*} openId 
     */
    async queryMyGifts(content, openId) {
        let raffle = await dataKit.findOne(content, 'raffle',
            {
                openId: openId
            }
        );

        return raffle ? { code: 0, data: raffle.gift_id} : {code: 0 , data: []}
    },
    /**
     * 日志记录【如果还有什么活动值变化也需要加入到字段中】
     * @param {*} content 
     * @param {*} openId 
     * @param {*} nick_name 
     * @param {*} type 活动类型，比如：签到，分享等
     */
    async logRecord(content, openId, nick_name, type){
        const currentTime = dateKit.getCurrentDateTime()

        let param = {
            openId: openId,
            nick_name: nick_name,
            create_time: currentTime,
            type: type
        }

        await dataKit.insertOne(content, 'logs', param)
    },
    /**
     * 根据数组索引删除值
     * @param {*} arr 
     * @param {*} index 
     */
    async delArrByIndex(arr,index) {
        if(arr == null || arr.length <=0){
            console.log('传递的数组为空')
            return arr
        }

        arr.splice(index, 1)
        return arr
    }
}
=======
const dataKit = require("./dataKit")
const dateKit = require("./dateKit")
const util = require('./util.js')
/**
 * 注意：使用await的方法必须加上async，不然会报错！！
 */
module.exports = {
    /**
    * 更新数据
    * @param {*} context 会话
    * @param {*} tableName  表名
    * @param {*} filter  新数据
    * @param {*} data  新数据
    * @result  data  返回对象
    */
    async update(context, tableName, filter, data) {
        if (!filter) {
            const msg = "filter不存在，无法更新";
            console.info(msg);
            return { code: -1, msg: msg }
        }
        const cloud = context.cloud;
        const result = await cloud.db.collection(tableName).updateMany(
            filter,
            { $set: data }
        );
        console.info("updateMany done, result:", result)
        return result;
    },
    /**
     * 根据名称获取商户
     * @param {*} openId 商户的openid
     */
    async getUserByOpenId(context, openId) {
        //过滤条件
        const filter = { openId: openId };
        let merchant = await dataKit.findOne(context, "user_info", filter);
        return merchant;
    },
    /**
     * 根据openId获取商户
     * @param {*} openId 商户的openid
     */
    async getMerchantByOpenId(context, openId) {
        if (!openId) {
            console.info("getMerchantByOpenId --> openId是必须的");
            return null;
        }
        //过滤条件
        const filter = { openId: openId };
        let merchant = await dataKit.findOne(context, "merchant_info", filter);
        return merchant;
    },
    /**
     * 获取商户的AccessToken
     * @param {*} openId 商户的openid
     */
    async getMerchantAccessToken(context, openId) {
        const merchant = await this.getMerchantByOpenId(context, openId);
        return merchant.accessToken;
    },
    /**
     * 获取商户唯一的商户AccessToken
     */
    async getDefaultMerchantAccessToken(context) {
        //过滤条件
        const filter = {};
        let merchant = await dataKit.findOne(context, "merchant_info", filter);
        return merchant.accessToken;
    },
    /**
     * 商品列表
     * @param {*} context 
     * @param {*} openId 商户的openid
     * @param {*} cid 类目id
     */
    async getProductList(context) {
        const accessToken = await this.getDefaultMerchantAccessToken(context);
        const result = await context.cloud.topApi.invoke({
            api: 'taobao.items.onsale.get',
            autoSession: false,
            data: {
                session: accessToken,
                fields: "num_iid,title,cid,price,pic_url",
                page_size: 200
            }
        });
        return result;
    },
    /**
     * 判断用户是否是会员
     * @param {*} context 上下文
     * @param {*} access_token 商家 token
     * @param {*} mix_nick 用户 mix_nick
     */
    async taobaoApiToMember(context, access_token, mix_nick) {
        const identity = await context.cloud.topApi.invoke({
            api: 'taobao.crm.member.identity.get',
            autoSession: false,
            data: {
                session: access_token,
                mix_nick: mix_nick
            }
        });
        if (identity.result.member_info) {// 是会员
            return { flag: true };
        } else {
            return { flag: false };
        }
    },
    /**
     * 查询用户淘宝订单列表
     * @param {*} context 
     * @param {*} access_token 商家 token
     * @param {*} open_id 用户open_id
     * @param {Object} param 参数
     *  @param {String} access_token 用户token
     *  @param {String} open_id 用户 open_id
     *  @param {String} start_created 查询范围开始时间
     *  @param {String} end_created 结束时间
     */
    async taobaoApiToSoldOrders(context, param) {
        const trades = await context.cloud.topApi.invoke({
            api: 'taobao.open.trades.sold.get',
            autoSession: false,
            data: {
                session: param.access_token,
                fields: 'tid,orders,created,status',
                buyer_open_id: param.openId,
                // buyer_open_id: 'AAE_2K8_AMYB12Kq6O03zKh_',
                start_created: param.start_time,
                end_created: param.end_time,
                //type: 'tmall_i18n',
                //status: 'TRADE_FINISHED',// 交易成功   //WAIT_BUYER_PAY    付定金
                page_no: 1,
                page_size: 100
            }
        });

        return trades

        // 判断用户是否有购买过订单
        if (!trades || total_results <= 0) {
            return false;
        } else {
            return true;
        }
    },
    /**
     * 增加抽奖机会
     * @param {*} content 
     * @param {*} num 增加的幸运值数量 
     * @param {*} nick_name 
     * @param {*} openId 
     */
    async add(content, num, nick_name, openId) {
        const currentTime = dateKit.getCurrentDateTime()

        let result = await dataKit.findOne(content, 'ticket',
            {
                openId: openId
            }
        );

        if (!result) {
            result = {
                openId: openId,
                nick_name: nick_name,
                create_time: currentTime,
                update_time: currentTime,
                ticket_time: '',
                ticket_id: [],
                luck_value: 0,
                num: [], //该num值为卡片的序号值
                count: 2,
                flag: 0
            }
        }

        result.update_time = currentTime
        result.luck_value = result.luck_value + num
        await dataKit.insertOrUpdate(content, 'ticket', result)
    },
    /**
     * 抽卡
     * @param {*} content 
     * @param {*} num 卡片序号
     * @param {*} openId 
     * @param {*} count  每日抽卡的次数 
     * @param {*} flag  判断是第几次抽卡，决定中奖概率
     */
    async card(content, num, result, count, flag) {
        const currentTime = dateKit.getCurrentDateTime()

        if (num === null || num === undefined) {
            console.log('==============没有传递正确的num值============')
            return false
        }

        //取出卡片
        let card = await dataKit.findOne(content, 'cards',
            {
                num: num
            }
        );
        console.info('抽出的卡片为：', card)

        result.update_time = currentTime
        result.luck_value = result.luck_value - 2 // 抽卡消耗2点幸运值
        result.ticket_id.push(card._id)
        result.num.push(num)
        result.count = count
        result.ticket_time = currentTime
        result.flag = flag
        await dataKit.insertOrUpdate(content, 'ticket', result)

        //返回卡片信息给前端
        return card;
    },
    /**
     * 测试文字识别
     * @param {*} context 
     * @param {*} access_token 
     * @param {*} mix_nick 
     */
    async test(context) {
        const identity = await context.cloud.topApi.invoke({
            api: 'aliyun.viapi.ocr.character',
            autoSession: false,
            data: {
                image_url: "https://img.alicdn.com/imgextra/i1/4161056916/O1CN01rmLoNz20xZobkRvUq_!!4161056916.jpg",
                min_height: 1000
            }
        });

        return identity;
    },
    /**
     * 是否中奖
     * @param {*} content 
     */
    async isGift(content, openId) {
        let result = await dataKit.findOne(content, 'gift_record',
            {
                openId: openId
            }
        );

        return result;
    },
    /**
     * 用户抽取优惠券消耗幸运值
     * @param {*} content 
     * @param {*} openId 
     */
    async decreame(content, openId) {
        let result = await dataKit.findOne(content, 'ticket',
            {
                openId: openId
            }
        );

        result.luck_value = result.luck_value - 1
        await dataKit.updateBy_id(content, 'ticket', result)
    },
    /**
     * 修改抽奖表，规约每日只能抽取一次奖品
     * @param {*} content 
     * @param {*} param 抽奖表 
     */
    async raffle(content, param) {
        param.update_time = dateKit.getCurrentDateTime()
        await dataKit.updateBy_id(content, 'raffle', param)
    },
    /**
     * (用户第一次抽奖，新建该表)
     * @param {*} content 
     * @param {*} param 抽奖表 
     * @param {*} ticket 
     */
    async first(content, openId, nick_name) {
        const c = dateKit.getCurrentDateTime()

        var param = {
            openId: openId,
            create_time: c,
            update_time: c,
            gift_id: [],
            count: 2,
            nick_name: nick_name
        }

        await dataKit.insertOne(content, 'raffle', param)
    },
    /**
     * 判断数组是否包含
     * @param {*} arr 
     * @param {*} item 
     */
    contain(arr, item) {
        if (arr != null && arr.length > 0 && arr != undefined) {
            for (let key of arr) {
                if (item === key) {
                    return true
                }
            }

            return false
        }

        return false
    },
    /**
     * 层级抽卡,根据数组来判断是24号前还是后
     * 根据bool得知是否中奖
     * @param {*} result 
     * @param {*} count 今日还剩几次抽卡，1表示第一次，0表示今日两次机会完了
     * rate 中奖的概率
     * arr 用来操作的数组
     * num 抽卡层级，分别为1,2，3
     */
    async one(result, count, twoFourArr, rate, content, num, openId) {
        console.info('==========one is running==============')
        const currentTime = dateKit.getCurrentDateTime()

        const r = dateKit.getRandom(1, 100)

        if (r > rate) {
            console.log('没有抽中卡片修改相关数据')
            result.flag = num
            result.update_time = currentTime
            result.ticket_time = currentTime
            result.luck_value = result.luck_value - 2

            if (result.count === 1) {
                result.count = result.count - 1
            } else if (result.count === 0) {
                //此处表示今日重置次数
                result.count = 1
            } else {
                result.count = result.count - 1
            }

            await dataKit.insertOrUpdate(content, 'ticket', result)

            return false
        }

        var residueArr = result.num //使用卡片序号获取没有抽中的卡片
        console.log('已经抽中的塔罗牌：', residueArr)

        for (let index = 0; index < twoFourArr.length; index++) {
            //把已经中奖的卡片排出去
            for (let i = 0; i < residueArr.length; i++) {
                if (twoFourArr[index] == residueArr[i]) {
                    twoFourArr.splice(index, 1)
                    index = index - 1
                    break
                }
            }
        }

        console.log('最后排除后的数组为：', twoFourArr)
        let twoResult = dateKit.getRandom(0, twoFourArr.length - 1)

        console.log('最后的随机结果为：', twoResult)
        console.log('传递的num值为：', twoFourArr[twoResult])
        let lastResult = await this.card(content, twoFourArr[twoResult], result, count, 1) //抽中了则需要把flag重置为1层级

        if (lastResult) {
            return { code: 0, data: lastResult }
        }

        console.log('card方法出错，card结果为：', lastResult)
        return false
    },
    /**
     * @return 返回奖品信息【1】，否则全部为没有中奖
     * @param {*} content 
     * @param {*} len 塔罗牌数量
     * @param {*} raffle raffle信息
     * @param {*} ticket  ticket信息
     */
    async gift01(content, len, raffle, ticket, openId, nick_name) {
        const currTime = dateKit.getCurrentDateTime()

        if (!len) {
            return { code: -1, msg: '传入的塔罗牌数量为空' }
        }

        var wu = await dataKit.findOne(content, 'gift',
            {
                num: 1
            }
        );

        console.log('传入的len为：', len)
        //每个等级都可以抽取优惠券
        switch (len) {
            case 1:
            case 2:
                let r = dateKit.getRandom(1, 1000)
                if (wu.rate >= r) {
                    //抽中奖品,判断库存
                    if (wu.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.quan(wu, raffle, content)
                    return { code: 1, data: wu } //抽中奖品后返回信息
                }

                await this.without(raffle, content)
                return { code: 0, msg: '' }
            case 3:
            case 4: //可以抽中1和3
                let three = await dataKit.findOne(content, 'gift',
                    {
                        num: 3
                    }
                );

                let x = dateKit.getRandom(1, 1000)

                //抽去1
                if (wu.rate > x) {
                    if (wu.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.quan(wu, raffle, content)
                    return { code: 1, data: wu } //抽中奖品后返回信息
                }

                if (three.rate >= x) {
                    //抽中奖品,判断库存
                    if (three.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(three, raffle, openId, nick_name, content)
                    return { code: 1, data: three }
                }

                await this.without(raffle, content)
                return { code: 0, msg: '' }
            case 5: //可以抽取1和3和5
                let five = await dataKit.findOne(content, 'gift',
                    {
                        num: 5
                    }
                );

                let y = dateKit.getRandom(1, 1000)

                //抽去1
                if (wu.rate > y) {
                    if (wu.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.quan(wu, raffle, content)
                    return { code: 1, data: wu } //抽中奖品后返回信息
                }

                //抽取3
                let three01 = await dataKit.findOne(content, 'gift',
                    {
                        num: 3
                    }
                );

                if (three01.rate >= y) {
                    //抽中奖品,判断库存
                    if (three01.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(three01, raffle, openId, nick_name, content)
                    return { code: 1, data: three01 }
                }

                if (five.rate >= y) {
                    //抽中奖品,判断库存
                    if (five.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(five, raffle, openId, nick_name, content)
                    return { code: 1, data: five }
                }

                await this.without(raffle, content)
                return { code: 0, msg: '' }
            case 6: //还可以抽取1,3,5,6
                let six = await dataKit.findOne(content, 'gift',
                    {
                        num: 6
                    }
                );

                let s = dateKit.getRandom(1, 1000)

                //抽去1
                if (wu.rate > s) {
                    if (wu.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.quan(wu, raffle, content)
                    return { code: 1, data: wu } //抽中奖品后返回信息
                }

                //抽取3
                let three02 = await dataKit.findOne(content, 'gift',
                    {
                        num: 3
                    }
                );

                if (three02.rate >= s) {
                    //抽中奖品,判断库存
                    if (three02.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(three02, raffle, openId, nick_name, content)
                    return { code: 1, data: three02 }
                }

                //抽取5
                let five01 = await dataKit.findOne(content, 'gift',
                    {
                        num: 5
                    }
                );

                if (five01.rate >= s) {
                    //抽中奖品,判断库存
                    if (five01.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(five01, raffle, openId, nick_name, content)
                    return { code: 1, data: five01 }
                }

                if (six.rate >= s) {
                    //抽中奖品,判断库存
                    if (six.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(six, raffle, openId, nick_name, content)
                    return { code: 1, data: six }
                }

                await this.without(raffle, content)
                return { code: 0, msg: '' }
            case 7: //可以抽取1,3,5,6,7
            case 8:
                let theven = await dataKit.findOne(content, 'gift',
                    {
                        num: 7
                    }
                );

                let t = dateKit.getRandom(1, 1000)

                //抽去1
                if (wu.rate > t) {
                    if (wu.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.quan(wu, raffle, content)
                    return { code: 1, data: wu } //抽中奖品后返回信息
                }

                //抽取3
                let three03 = await dataKit.findOne(content, 'gift',
                    {
                        num: 3
                    }
                );

                if (three03.rate >= t) {
                    //抽中奖品,判断库存
                    if (three03.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(three03, raffle, openId, nick_name, content)
                    return { code: 1, data: three03 }
                }

                //抽取5
                let five02 = await dataKit.findOne(content, 'gift',
                    {
                        num: 5
                    }
                );

                if (five02.rate >= t) {
                    //抽中奖品,判断库存
                    if (fivfive02e.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(five02, raffle, openId, nick_name, content)
                    return { code: 1, data: five02 }
                }

                //抽取6
                let six01 = await dataKit.findOne(content, 'gift',
                    {
                        num: 6
                    }
                );

                if (six01.rate >= t) {
                    //抽中奖品,判断库存
                    if (six01.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(six01, raffle, openId, nick_name, content)
                    return { code: 1, data: six01 }
                }

                if (theven.rate >= t) {
                    //抽中奖品,判断库存
                    if (theven.count <= 0) {
                        await this.without(raffle, content)
                        return { code: -3, msg: '库存不足' }
                    }

                    await this.sure(theven, raffle, openId, nick_name, content)
                    return { code: 1, data: theven }
                }

                await this.without(raffle, content)
                return { code: 0, msg: '' }
            default:
                raffle.count = raffle.count - 1
                raffle.update_time = currTime //最后一次抽奖时间
                raffle.ticket_time = currTime
                await dataKit.insertOrUpdate(content, 'raffle', raffle)
                return { code: -2, msg: '该塔罗牌数量不能抽奖' };
        }
    },
    /**
     * 抽奖接口，支持按照平均每天的形式来分发奖品
     * 中奖形式按照数组来做
     * 加一个字段is_dup来控制该奖品是否可以重复被抽中
     * 此方法的raffle表一定不能为空，在index中提前进行一次新建操作
     * 
     * 涉及表：gift（奖品表），record（中奖记录表），raffle（中奖需要的条件信息，比如一天几次）
     * @param {*} content 
     * @param {*} raffle 
     * @param {*} openId 
     * @param {*} nick_name 
     */
    async giftByArr(content, raffle, openId, nick_name) {
        const currentStamp = dateKit.getRealTime()

        let start_time = dateKit.changeToTimestamp('2020-11-01')
        let end_time = dateKit.changeToTimestamp('2020-11-01')

        if (currentStamp > end_time || currentStamp < start_time) {
            return { code: -1, msg: '当前时间不在抽奖时间里面' }
        }

        let giftResult = await dataKit.find(content, 'gift', {})

        //产生的随机数
        let r = dateKit.getRandom(1, 100)

        var gift;

        if (new Date(currentStamp).toDateString() === new Date(raffle.ticket_time).toDateString()) {
            if (raffle.count <= 0) {
                return { code: -2, msg: '今日抽奖次数已经上限' }
            }

            //执行抽奖逻辑
            for (let i = 0; i < giftResult.length; i++) {
                let rate = giftResult[i].rate
                if (r <= rate[1] && r >= rate[0]) {
                    gift = giftResult[i]
                }
            }

            console.log('抽中的奖品是：', gift)
            if (!gift) {
                console.log('没有匹配的奖品，该区间为不中奖')
                await this.without(raffle, content)
                return { code: -3, msg: '很遗憾没有抽中奖品' }
            }

            //判断库存,此处涉及到数字切记不要当成对象来判断，注意01操作
            if (gift.count != null && gift.count != undefined) {
                if (gift.count <= 0) {
                    console.log('该奖品库存不足')
                    await this.without(raffle, content)
                    return { code: -3, msg: '很遗憾没有抽中奖品' }
                }
            }

            //判断每天的库存数量
            if (gift.day_count != null && gift.day_count != undefined) {
                if (gift.day_count <= 0) {
                    console.log('该奖品今日抽取数量已经上限')
                    await this.without(raffle, content)
                    return { code: -3, msg: '很遗憾没有抽中奖品' }
                }
            }

            //判断该奖品是否可以被重复抽中,0表示可以被重复抽中，1表示不可以被重复抽中
            if (gift.is_dup) {
                let record = await dataKit.findOne(content, 'record',
                    {
                        openId: openId,
                        gift_id: gift._id
                    }
                )

                if (record) {
                    console.log('该奖品不能重复抽中')
                    await this.without(raffle, content)
                    return { code: -3, msg: '很遗憾没有抽中奖品' }
                }
            }

            //乐观锁判断库存，该处已经修改过奖品表了，因此后续切记不要重复扣减库存
            let version = gift.version
            gift.version++;
            gift.count--;

            let updateResult = await dataKit.update(content, 'gift',
                {
                    version: version,
                    _id: gift._id
                },
                gift
            );

            if (updateResult === 0) {
                await this.without(raffle, content)
                console.log('该奖品已经被修改过')
                return { code: -3, msg: '很遗憾没有抽中奖品' }
            }

            //抽中奖品，执行数据表修改
            await this.sure(gift, raffle, openId, nick_name)
            return { code: 0, data: gift }
        }

        //第二天，则不用判断抽奖次数
        //执行抽奖逻辑
        for (let i = 0; i < giftResult.length; i++) {
            let rate = giftResult[i].rate
            if (r <= rate[1] && r >= rate[0]) {
                gift = giftResult[i]
            }
        }

        console.log('抽中的奖品是：', gift)
        if (!gift) {
            console.log('没有匹配的奖品，该区间为不中奖')
            await this.without(raffle, content)
            return { code: -3, msg: '很遗憾没有抽中奖品' }
        }

        //判断库存,此处涉及到数字切记不要当成对象来判断，注意01操作
        if (gift.count != null && gift.count != undefined) {
            if (gift.count <= 0) {
                console.log('该奖品库存不足')
                await this.without(raffle, content)
                return { code: -3, msg: '很遗憾没有抽中奖品' }
            }
        }

        //判断每天的库存数量
        if (gift.day_count != null && gift.day_count != undefined) {
            if (gift.day_count <= 0) {
                console.log('该奖品今日抽取数量已经上限')
                await this.without(raffle, content)
                return { code: -3, msg: '很遗憾没有抽中奖品' }
            }
        }

        //判断该奖品是否可以被重复抽中,0表示可以被重复抽中，1表示不可以被重复抽中
        if (gift.is_dup) {
            let record = await dataKit.findOne(content, 'record',
                {
                    openId: openId,
                    gift_id: gift._id
                }
            )

            if (record) {
                console.log('该奖品不能重复抽中')
                await this.without(raffle, content)
                return { code: -3, msg: '很遗憾没有抽中奖品' }
            }
        }

        //乐观锁判断库存，该处已经修改过奖品表了，因此后续切记不要重复扣减库存
        let version = gift.version
        gift.version++;
        gift.count--;

        let updateResult = await dataKit.update(content, 'gift',
            {
                version: version,
                _id: gift._id
            },
            gift
        );

        if (updateResult === 0) {
            await this.without(raffle, content)
            console.log('该奖品已经被修改过')
            return { code: -3, msg: '很遗憾没有抽中奖品' }
        }

        //抽中奖品，执行数据表修改
        await this.sure(gift, raffle, openId, nick_name)
        return { code: 0, data: gift }
    },
    /**
     * 没有中奖修改抽奖表，后续如果有什么扣减积分的操作也是可以新增字段的
     */
    async without(raffle, content) {
        const currTime = dateKit.getCurrentDateTime()
        raffle.count = raffle.count - 1
        raffle.update_time = currTime
        raffle.ticket_time = currTime //最后一次抽奖时间
        await dataKit.insertOrUpdate(content, 'raffle', raffle)
    },
    /**
     * 中奖
     * @param {*} result  gift信息
     * @param {*} raffle  raffle信息
     */
    async sure(result, raffle, openId, nick_name, content) {
        console.log('sure方法执行成功')
        const currTime = dateKit.getCurrentDateTime()

        //抽中奖品修改相关表
        //1. gift
        // result.count = result.count - 1
        result.day_count = result.day_count - 1
        await dataKit.insertOrUpdate(content, 'gift', result)

        //2. raffle, 在index需要判断今日是否还能抽奖,并重置[如果是第一次则先新增数据]
        raffle.count = raffle.count - 1
        raffle.update_time = currTime //最后一次抽奖时间
        raffle.ticket_time = currTime
        raffle.gift_id.push(result._id)
        await dataKit.insertOrUpdate(content, 'raffle', raffle)

        //3.record 独立一个奖品记录表
        let record = {
            openId: openId,
            nick_name: nick_name,
            create_time: currTime,
            gift_id: result._id,
            gift_name: result.name
        }

        await dataKit.insertOne(content, 'record', record)
    },
    /**
     * 查询每日的一个中奖名单
     */
    async queryGiftRecord(content, openId) {
        const currentDate = dateKit.getCurrentDate()
        let start = currentDate + ' 00:00:00'
        let end = currentDate + ' 23:59:59'

        //该表记得添加联合索引
        let result = await dataKit.find(content, 'record', 
            {
                create_time: {
                    $gte: start,
                    $lte: end
                },
                openId: openId
            }
        );

        return result
    },
    /**
     * 浏览商品到达一定数量后增加幸运值
     * @param {*} product 
     * @param {*} content 
     * @param {*} nick_name 
     * @param {*} openId 
     */
    async viewAdd(product, content, nick_name, openId) {
        console.log('viewAdd方法执行============')
        var len = product.goods_id.length

        let a = parseInt(len / 5)
        if (a <= 3 && a > 0) {
            //第几个5次
            switch (a) {
                case 1:
                    //判断是否增加过幸运值
                    if (product.count === 2) {
                        return { msg: '已经增加幸运奖' }
                    }

                    this.add(content, 1, nick_name, openId)

                    //把浏览商品表数据修改
                    product.count = 2
                    await dataKit.updateBy_id(content, 'product', product)
                    return;
                case 2:
                    //判断是否增加过幸运值
                    if (product.count === 1) {
                        return { msg: '已经增加幸运奖' }
                    }

                    this.add(content, 1, nick_name, openId)

                    //把浏览商品表数据修改
                    product.count = 1
                    await dataKit.updateBy_id(content, 'product', product)
                    return;
                case 3:
                    //判断是否增加过幸运值
                    if (product.count === 0) {
                        return { msg: '已经增加幸运奖' }
                    }

                    this.add(content, 1, nick_name, openId)

                    //把浏览商品表数据修改
                    product.count = 0
                    await dataKit.updateBy_id(content, 'product', product)
                    return;
                default:
                    return
            }
        }
        let count = parseInt(a / 3) //整除两次得到第几次机会
        if (count > 0) {
            //第几个5次
            switch (count) {
                case 1:
                    //判断是否增加过幸运值
                    if (product.count === 2) {
                        return { msg: '已经增加幸运奖' }
                    }

                    this.add(content, 1, nick_name, openId)

                    //把浏览商品表数据修改
                    product.count = 2
                    await dataKit.updateBy_id(content, 'product', product)
                    return;
                case 2:
                    //判断是否增加过幸运值
                    if (product.count === 1) {
                        return { msg: '已经增加幸运奖' }
                    }

                    this.add(content, 1, nick_name, openId)

                    //把浏览商品表数据修改
                    product.count = 1
                    await dataKit.updateBy_id(content, 'product', product)
                    return;
                case 3:
                    //判断是否增加过幸运值
                    if (product.count === 0) {
                        return { msg: '已经增加幸运奖' }
                    }

                    this.add(content, 1, nick_name, openId)

                    //把浏览商品表数据修改
                    product.count = 0
                    await dataKit.updateBy_id(content, 'product', product)
                    return;
                default:
                    return
            }
        }
    },
    /**
    * 执行成功
    * @param {*} data 
    */
    toSuccess(data) {
        if (data) {
            return { code: 0, msg: '操作成功', data: data }
        }

        return { code: 0, msg: '操作成功' }
    },
    /**
     * 执行失败
     * @param {*} msg 
     */
    toFail(msg) {
        return { code: -1, msg: msg ? '操作失败' : msg }
    },
    /**对于数字类型的返回封装
     * @param {*} count
     * @param {*} value
     * @param {*} flag
     */
    toCount() {
        var len = arguments.length

        switch (len) {
            case 1:
                return { count: arguments[0] }
            case 2:
                return { count: arguments[0], value: arguments[1] }
            case 3:
                return { count: arguments[0], value: arguments[1], flag: arguments[2] }
            default:
                return this.toFail('暂时只支持3个值的传递')
        }
    },
    /**
     * 对于字符串类型字段的查询今日
     * @param {*} content 
     * @param {*} tableName 
     * @param {*} filter 
     */
    async getTodayData(content, tableName, filter) {
        let a = util.checkIsNull(content, tableName)
        if (!a) {
            return a
        }

        let currentDate = dateKit.getCurrentDate()

        let start = currentDate + ' 00:00:00'
        let end = currentDate + ' 23:59:59'

        const result = await dataKit.find(content, tableName,
            {
                create_time: {
                    $gte: start,
                    $lte: end
                }
            },
            filter
        )

        return result
    },
    /**
     * 获取格式化字符串时间的数据，该表应该被建立时间字段的一个索引
     * @param {*} content 
     * @param {*} tableName 
     * @param {*} start 开始时间（字符串类型）
     * @param {*} end 结束时间（字符串类型）
     * @param {*} filter 过滤条件，比如前10条数据
     */
    async getDataForStrDate(content, tableName, start, end, filter) {
        let a = util.checkIsNull(content, tableName, start, end)
        if (!a) {
            return a
        }

        let a = new Date(start)
        let b = new Date(end)

        if (a == 'Invalid Date' || b == 'Invalid Date') {
            return { code: -2, msg: '请传入正确格式的时间：\'2020-11-11 16:15:15\'' }
        }

        const result = await dataKit.find(content, tableName,
            {
                create_time: {
                    $gte: start,
                    $lte: end
                }
            },
            filter
        )

        return result
    },
    /**
     * 判断今日是否做过活动了（签到， 分享， 浏览商品， 收藏店铺， 购买， 入会）
     * 现在修改为每次打卡都是一条数据
     * @param {*} content 
     * @param {*} tableName 
     * @param {*} openId 
     * @param {*} keyName 用来判断今日活动的时间的属性名
     */
    async isActon(content, tableName, openId, keyName) {
        const result = await dataKit.findNew(content, tableName,
            {
                openId: openId
            }
        )

        if (!result) {
            return { flag: false }
        }

        const currentStamp = dateKit.getRealTime()

        let compareTime = new Date(dateKit.changeToTimestamp(result[keyName])).toDateString()
        if (new Date(currentStamp).toDateString() === compareTime) {
            return { flag: true }
        }

        return { flag: false }
    },
    /**
     * 返回今日活动还剩余的次数
     * @param {*} content 
     * @param {*} tableName 
     * @param {*} openId 
     * @param {*} keyName 数据表中时间的列名
     * @param {*} countName 数据表中次数的列名
     * @param {*} count 一天的次数
     */
    async getActionCount(content, tableName, openId, keyName, countName, count) {
        const result = await dataKit.findNew(content, tableName,
            {
                openId: openId
            }
        )

        if (!result) {
            //返回默认的最高次数
            return this.toCount(count)
        }

        const currentStamp = dateKit.getRealTime()

        let compareTime = new Date(dateKit.changeToTimestamp(result[keyName])).toDateString()
        if (new Date(currentStamp).toDateString() === compareTime) {
            return this.toCount(result[countName])
        }

        return this.toCount(count)
    },
    /**
     * 做完活动后减少每日可做该活动次数
     * @param {*} content 
     * @param {*} tableName 
     * @param {*} openId 
     * @param {*} nick_name 
     * @param {*} totalCount 一天可做活动总数
     */
    async actionDecCount(content, tableName, openId, nick_name, totalCount) {
        const currentTime = dateKit.getCurrentDateTime()

        const result = await dataKit.findNew(content, tableName,
            {
                openId: openId
            }
        )

        //次数名称定死为count
        if (!result) {
            result = {
                openId: openId,
                nick_name: nick_name,
                create_time: currentTime,
                update_time: currentTime,
                count: totalCount - 1
            }
            await dataKit.insertOne(content, tableName, result)

            return true
        }

        result.update_time = currentTime
        result.count = result.count - 1
        await dataKit.updateBy_id(content, tableName, result)
        return true
    },
    /**
     * 重置每日奖品为平均数量
     * @param {*} totalDay 需要抽奖的总时长
     */
    async resetGiftCount(content, totalDay) {
        let gift = await dataKit.find(content, 'gift', {})

        for (let index = 0; index < gift.length; index++) {
            let element = gift[index];
            if(element.day_count != null && element.day_count != undefined){
                //向下取整
                let countForDay = parseInt(element.count / totalDay)
                element.day_count = countForDay
                await dataKit.updateBy_id(content, 'gift', element)
            }
        }

        return '重置每日奖品数量成功了'
    },
    /**
     * 查询我的奖品列表
     * @param {*} content 
     * @param {*} openId 
     */
    async queryMyGifts(content, openId) {
        let raffle = await dataKit.findOne(content, 'raffle',
            {
                openId: openId
            }
        );

        return raffle ? { code: 0, data: raffle.gift_id} : {code: 0 , data: []}
    },
    /**
     * 日志记录【如果还有什么活动值变化也需要加入到字段中】
     * @param {*} content 
     * @param {*} openId 
     * @param {*} nick_name 
     * @param {*} type 活动类型，比如：签到，分享等
     */
    async logRecord(content, openId, nick_name, type){
        const currentTime = dateKit.getCurrentDateTime()

        let param = {
            openId: openId,
            nick_name: nick_name,
            create_time: currentTime,
            type: type
        }

        await dataKit.insertOne(content, 'logs', param)
    },
    /**
     * 根据数组索引删除值
     * @param {*} arr 
     * @param {*} index 
     */
    async delArrByIndex(arr,index) {
        if(arr == null || arr.length <=0){
            console.log('传递的数组为空')
            return arr
        }

        arr.splice(index, 1)
        return arr
    }
}
>>>>>>> e1223b7bbde685140547af0cd62a05ca9b2e57ed
